####
## Version information
####

# Library version
#
# This should be incremented with every release.  See semver.org.
set (SQUASH_VERSION_MAJOR    0)
set (SQUASH_VERSION_MINOR    8)
set (SQUASH_VERSION_REVISION 0)

# API version.
#
# This will go in the pkg-config and shared library names.  Should
# only be changed if the API breaks backwards compatibility.
set (SQUASH_VERSION_API      "0.8")

# ABI version
#
# Rules from § 11.4: Library Versioning of the autobook
# https://www.sourceware.org/autobook/autobook/autobook_61.html
#
# 1) If you have changed any of the sources for this library, the
#    revision number must be incremented. This is a new revision of
#    the current interface.
# 2) If the interface has changed, then current must be incremented,
#    and revision reset to ‘0’. This is the first revision of a new
#    interface.
# 3) If the new interface is a superset of the previous interface
#    (that is, if the previous interface has not been broken by the
#    changes in this new release), then age must be incremented. This
#    release is backwards compatible with the previous release.
# 4) If the new interface has removed elements with respect to the
#    previous interface, then you have broken backward compatibility
#    and age must be reset to ‘0’. This release has a new, but
#    backwards incompatible interface.
#
# Conveniently, this also matches semantic versioning for the most
# part (API changes are a bit more complicated since we change the
# library and pkg-config names and can reset these to whatever we
# want, but we don't *have* to.
set (SQUASH_SOVERSION_CURRENT  ${SQUASH_VERSION_MAJOR})
set (SQUASH_SOVERSION_REVISION ${SQUASH_VERSION_MINOR})
set (SQUASH_SOVERSION_AGE      ${SQUASH_VERSION_REVISION})

cmake_minimum_required (VERSION 2.8.6)

if (CMAKE_BUILD_TYPE STREQUAL "")
  set (CMAKE_BUILD_TYPE "Debug")
endif ()

if (CMAKE_VERSION VERSION_GREATER 3.1.2)
  cmake_policy (SET CMP0054 NEW)
endif ()

set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)

project (squash)

include (GNUInstallDirs)
include (ExtraWarningFlags)
include (CheckFunctionExists)
include (CheckIncludeFile)
include (AddCompilerFlags)

set(THREADS_PREFER_PTHREAD_FLAG)
find_package (Threads REQUIRED)
find_package (CppCheck)

enable_testing ()

if (ENABLE_COVERAGE STREQUAL "yes")
  include (CodeCoverage)
endif ()

if (MSVC)
  global_add_compiler_flags (
    /wd4996)
  add_definitions (-D_CRT_SECURE_NO_WARNINGS)
endif (MSVC)

# https://cmake.org/Bug/view.php?id=8246
if(NOT MSVC)
  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin")
endif()

set (PACKAGE_NAME Squash)
set (SQUASH_TOP_SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}")
set (SQUASH_TOP_BUILDDIR "${CMAKE_CURRENT_BINARY_DIR}")

set (SQUASH_VERSION_MAJOR 0)
set (SQUASH_VERSION_MINOR 8)
set (SQUASH_VERSION_REVISION 0)
set (SQUASH_VERSION_API "0.8")
set (PACKAGE_VERSION ${SQUASH_VERSION_MAJOR}.${SQUASH_VERSION_MINOR}.${SQUASH_VERSION_REVISION})

if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/squash/tinycthread/source/tinycthread.c")
  message (FATAL_ERROR "It looks like you don't have submodules checked out.
If you are compiling from git, make sure to run `git submodule update --init --recursive' or call autogen.sh, which will invoke that command for you.
If you are compiling from a tarball, make sure you don't use the ones automatically generated by GitHub—they don't include submodules and are, therefore, completely broken.  Official releases are on https://github.com/quixdb/squash/releases and are the ones labeled \"squash-x.y.z.tar.bz2\", not \"Source code\".  GitHub is aware of the issue.")
endif ()

set(CPACK_PACKAGE_VERSION_MAJOR ${SQUASH_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${SQUASH_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${SQUASH_VERSION_REVISION})
set(CPACK_SOURCE_GENERATOR "TBZ2")
set(CPACK_SOURCE_PACKAGE_FILE_NAME
  "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_SOURCE_IGNORE_FILES
  "/autogen.sh;/build/;.git;.gitmodules;.gitignore;~$;${CPACK_SOURCE_IGNORE_FILES}")
include (CPack)

add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)

include_directories ("${CMAKE_CURRENT_BINARY_DIR}")
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}")

if ("${PLUGIN_DIRECTORY}" STREQUAL "")
  set (PLUGIN_DIRECTORY ${CMAKE_INSTALL_FULL_LIBDIR}/squash/${SQUASH_VERSION_API}/plugins)
endif ()

if ("${SEARCH_PATH}" STREQUAL "")
  set (SEARCH_PATH "${PLUGIN_DIRECTORY}")
endif ()

set (SQUASH_PLUGIN_DIRECTORY "${PLUGIN_DIRECTORY}")
set (SQUASH_SEARCH_PATH "${SEARCH_PATH}")

set (squash_enabled_plugins "" CACHE INTERNAL "enabled plugins" FORCE)

# This only works with gcc/clang at the moment.
function (squash_set_target_visibility target visibility)
  set (flag "-fvisibility=${visibility}")
  string (REGEX REPLACE "[-=]+" "_" abbrev_test_name "${flag}")

  CHECK_C_COMPILER_FLAG ("-fvisibility=${visibility}" "CFLAG_${abbrev_test_name}")
  CHECK_CXX_COMPILER_FLAG ("-fvisibility=${visibility}" "CXXFLAG_${abbrev_test_name}")

  if (CFLAG_${abbrev_test_name})
    target_add_compiler_flags (${target} ${flag})
    set_property (TARGET ${target} APPEND PROPERTY LINKER_FLAGS "${flag}")
  endif ()

  unset (flag)
  unset (abbrev_test_name)
endfunction (squash_set_target_visibility)

set_compiler_specific_flags(
  VARIABLE release_flags
  GCCISH -O3 -DNDEBUG
  MSVC /O2 /DNDEBUG)
foreach(flag ${release_flags})
  set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${flag}")
endforeach(flag)
unset(release_flags)

set_compiler_specific_flags(
  VARIABLE debug_flags
  GCCISH -g -O2
  MSVC /Od)
foreach(flag ${debug_flags})
  set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${flag}")
endforeach(flag)
unset(debug_flags)

if (ENABLE_COVERAGE)
  if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
    message(FATAL_ERROR "Coverage analysis requires a debug build.")
  endif()
endif()

set_directory_properties(PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

####
## Compatibility with older CMake
##
## This will probably be removed when Ubuntu bumps their LTS server
## release (and Travis upgrades).
####
if (${CMAKE_VERSION} VERSION_LESS 2.8.11)
  function (target_include_directories)
    foreach (argn RANGE 2 ${ARGC})
      if (${argn} LESS ${ARGC})
        include_directories (${ARGV${argn}})
      endif ()
    endforeach ()
  endfunction ()
endif ()

if (ENABLE_COVERAGE STREQUAL "yes")
  if (CMAKE_BUILD_TYPE MATCHES "Release")
    message (WARNING "Coverage anaysis requires a debugging build")
  endif ()
endif ()

if (ENABLE_SANITIZER)
  set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
  set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
endif ()

function (squash_target_add_coverage target)
  if (ENABLE_COVERAGE)
    set_property (TARGET ${target} APPEND_STRING PROPERTY COMPILE_FLAGS " -fprofile-arcs")
    set_property (TARGET ${target} APPEND_STRING PROPERTY COMPILE_FLAGS " -ftest-coverage")
    set_property (TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " -fprofile-arcs")
    set_property (TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " -ftest-coverage")
  endif ()
endfunction (squash_target_add_coverage)

add_subdirectory (squash)
add_subdirectory (plugins)
add_subdirectory (utils)
add_subdirectory (docs)
add_subdirectory (examples)
add_subdirectory (bindings)
add_subdirectory (tests)
add_subdirectory (packaging)

include (GenPkgConfig)
generate_pkg_config ("${CMAKE_CURRENT_BINARY_DIR}/squash-${SQUASH_VERSION_API}.pc"
  NAME Squash
  DESCRIPTION "Compression abstraction library"
  VERSION "${SQUASH_VERSION_MAJOR}.${SQUASH_VERSION_MINOR}.${SQUASH_VERSION_REVISION}"
  LIBRARIES "squash-${SQUASH_VERSION_API}"
  CFLAGS "-I\${includedir}/squash-${SQUASH_VERSION_API}")

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/squash-${SQUASH_VERSION_API}.pc"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

if (ENABLE_COVERAGE STREQUAL "yes")
  SETUP_TARGET_FOR_COVERAGE(lcov test coverage)
endif ()
